import { Injectable, NotFoundException, ConflictException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { TaskTemplate } from './entities/task-template.entity';
import { CreateTaskTemplateDto } from './dto/create-task-template.dto';
import { UpdateTaskTemplateDto } from './dto/update-task-template.dto';
import { TaskTemplateDto } from './dto/task-template.dto';

@Injectable()
export class TaskTemplatesService {
  constructor(
    @InjectRepository(TaskTemplate)
    private taskTemplateRepository: Repository<TaskTemplate>,
  ) {}

  async create(
    createTaskTemplateDto: CreateTaskTemplateDto,
    userId: string,
  ): Promise<TaskTemplateDto> {
    const taskTemplate = this.taskTemplateRepository.create({
      ...createTaskTemplateDto,
      createdBy: userId,
      version: 1,
      isDeleted: false,
    });

    const savedTemplate = await this.taskTemplateRepository.save(taskTemplate);
    return this.mapToDto(savedTemplate);
  }

  async findAll(title?: string): Promise<TaskTemplateDto[]> {
    const queryBuilder = this.taskTemplateRepository
      .createQueryBuilder('template')
      .where('template.is_deleted = :isDeleted', { isDeleted: false });

    if (title) {
      queryBuilder.andWhere('template.title ILIKE :title', { title: `%${title}%` });
    }

    const templates = await queryBuilder.getMany();
    return templates.map((template) => this.mapToDto(template));
  }

  async findOne(id: string): Promise<TaskTemplateDto> {
    const template = await this.taskTemplateRepository.findOne({
      where: { id, isDeleted: false },
    });

    if (!template) {
      throw new NotFoundException(`Task template with ID ${id} not found`);
    }

    return this.mapToDto(template);
  }

  async update(id: string, updateTaskTemplateDto: UpdateTaskTemplateDto): Promise<TaskTemplateDto> {
    const template = await this.taskTemplateRepository.findOne({
      where: { id, isDeleted: false },
    });

    if (!template) {
      throw new NotFoundException(`Task template with ID ${id} not found`);
    }

    // Increment version number
    const updatedTemplate = {
      ...template,
      ...updateTaskTemplateDto,
      version: template.version + 1,
    };

    const savedTemplate = await this.taskTemplateRepository.save(updatedTemplate);
    return this.mapToDto(savedTemplate);
  }

  async remove(id: string): Promise<void> {
    const template = await this.taskTemplateRepository.findOne({
      where: { id, isDeleted: false },
    });

    if (!template) {
      throw new NotFoundException(`Task template with ID ${id} not found`);
    }

    // Soft delete
    await this.taskTemplateRepository.update(id, { isDeleted: true });
  }

  private mapToDto(template: TaskTemplate): TaskTemplateDto {
    return {
      id: template.id,
      title: template.title,
      description: template.description,
      taskCategoryId: template.taskCategoryId,
      version: template.version,
      createdBy: template.createdBy,
      createdAt: template.createdAt,
      updatedAt: template.updatedAt,
      isDeleted: template.isDeleted,
    };
  }
}
